package service

import (
	"context"
	"go.uber.org/zap"
	"golang-sgg-daijia/api/v1"
	"golang-sgg-daijia/internal/repository/tencentcloud"
	"io"
	"mime/multipart"
	"strings"
	"time"
)

type OcrService interface {
	IDCardOCR(ctx context.Context, file *multipart.FileHeader) (*v1.IDCardOcrVo, error)
	DriverLicenseOcr(ctx context.Context, file *multipart.FileHeader) (*v1.DriverLicenseOcrVo, error)
}

func NewOcrService(
	service *Service,
	ocrCli tencentcloud.OcrClient,
	cosService CosService,
) OcrService {
	return &ocrService{
		Service:    service,
		ocrCli:     ocrCli,
		cosService: cosService,
	}
}

type ocrService struct {
	*Service
	ocrCli     tencentcloud.OcrClient
	cosService CosService
}

func (s *ocrService) IDCardOCR(ctx context.Context, file *multipart.FileHeader) (*v1.IDCardOcrVo, error) {
	f, err := file.Open()
	if err != nil {
		s.logger.WithContext(ctx).Error("ocrService|IDCardOCR|Open", zap.Error(err))
		return nil, err
	}
	image, err := io.ReadAll(f)
	if err != nil {
		s.logger.WithContext(ctx).Error("ocrService|IDCardOCR|ReadAll", zap.Error(err))
	}
	resp, err := s.ocrCli.IDCardOCR(ctx, image)
	if err != nil || resp == nil || resp.Response == nil {
		return nil, err
	}
	// 转换为Vo对象返回
	idCardOcrVo := &v1.IDCardOcrVo{}
	if resp.Response.Name != nil && *resp.Response.Name != "" {
		// 驾驶证正面
		idCardOcrVo.Name = *resp.Response.Name
		if *resp.Response.Sex == "男" {
			idCardOcrVo.Gender = "1"
		} else {
			idCardOcrVo.Gender = "2"
		}
		idCardOcrVo.Birthday, err = time.Parse("2006/1/2", *resp.Response.Birth)
		if err != nil {
			s.logger.WithContext(ctx).Error("ocrService|IDCardOCR|Parse", zap.Any("data", map[string]interface{}{
				"Birth": *resp.Response.Birth,
			}), zap.Error(err))
		}
		idCardOcrVo.IDCardNo = *resp.Response.IdNum
		idCardOcrVo.IDCardAddress = *resp.Response.Address

		// 上传身份证正面到腾讯云cos
		cosUploadVo, err := s.cosService.UploadFile(ctx, file, "idCard")
		if err != nil {
			return nil, err
		}
		idCardOcrVo.IDCardFrontUrl = cosUploadVo.Url
		idCardOcrVo.IDCardFrontShowUrl = cosUploadVo.ShowUrl
	} else {
		// 身份证反面
		//证件有效期："2010.07.21-2020.07.21"
		startEnd := strings.Split(*resp.Response.ValidDate, "-")
		var idCardExpireStr string
		if len(startEnd) == 2 {
			idCardExpireStr = startEnd[1]
		} else {
			s.logger.WithContext(ctx).Warn("ocrService|IDCardOCR|Parse", zap.Any("data", map[string]interface{}{
				"ValidDate": *resp.Response.ValidDate,
			}), zap.Error(err))
		}
		// 前端做法是：formData.value.idcardFrontUrl[0].originalData.idcardExpire || formData.value.idcardBackUrl[0].originalData.idcardExpire,
		// 而当正面没有idcardExpire时，返回的是时间默认值，而不是空字符串，所以不会读到反面返回的idcardExpire，所以我把前端中或前面一半去掉了
		idCardOcrVo.IDCardExpire, err = time.Parse("2006.01.02", idCardExpireStr)
		if err != nil {
			s.logger.WithContext(ctx).Error("ocrService|IDCardOCR|Parse", zap.Any("data", map[string]interface{}{
				"idCardExprie": idCardExpireStr,
			}), zap.Error(err))
		}
		//上传身份证反面图片到腾讯云cos
		cosUploadVo, err := s.cosService.UploadFile(ctx, file, "idCard")
		if err != nil {
			return nil, err
		}
		idCardOcrVo.IDCardBackUrl = cosUploadVo.Url
		idCardOcrVo.IDCardBackShowUrl = cosUploadVo.ShowUrl
	}
	return idCardOcrVo, nil
}

func (s *ocrService) DriverLicenseOcr(ctx context.Context, file *multipart.FileHeader) (*v1.DriverLicenseOcrVo, error) {
	f, err := file.Open()
	if err != nil {
		s.logger.WithContext(ctx).Error("ocrService|IDCardOCR|Open", zap.Error(err))
		return nil, err
	}
	image, err := io.ReadAll(f)
	if err != nil {
		s.logger.WithContext(ctx).Error("ocrService|IDCardOCR|ReadAll", zap.Error(err))
	}
	resp, err := s.ocrCli.DriverLicense(ctx, image)
	if err != nil || resp == nil || resp.Response == nil {
		return nil, err
	}
	// 转换为Vo对象返回
	driverLicenseOcrVo := &v1.DriverLicenseOcrVo{}
	if resp.Response.Name != nil {
		// 驾驶证正面
		driverLicenseOcrVo.Name = *resp.Response.Name
		driverLicenseOcrVo.DriverLicenseClazz = *resp.Response.DriverLicenseType
		driverLicenseOcrVo.DriverLicenseNo = *resp.Response.CardCode

		driverLicenseOcrVo.DriverLicenseIssueDate, err = time.Parse("2006-01-02", *resp.Response.DateOfFirstIssue)
		if err != nil {
			s.logger.WithContext(ctx).Error("ocrService|IDCardOCR|Parse", zap.Any("data", map[string]interface{}{
				"Birth": *resp.Response.DateOfFirstIssue,
			}), zap.Error(err))
		}
		driverLicenseOcrVo.DriverLicenseExpire, err = time.Parse("2006-01-02", *resp.Response.EndDate)
		if err != nil {
			s.logger.WithContext(ctx).Error("ocrService|IDCardOCR|Parse", zap.Any("data", map[string]interface{}{
				"Birth": *resp.Response.EndDate,
			}), zap.Error(err))
		}

		// 上传驾驶证正面到腾讯云cos
		cosUploadVo, err := s.cosService.UploadFile(ctx, file, "driverLicense")
		if err != nil {
			return nil, err
		}
		driverLicenseOcrVo.DriverLicenseFrontUrl = cosUploadVo.Url
		driverLicenseOcrVo.DriverLicenseFrontShowUrl = cosUploadVo.ShowUrl
	} else {
		// 驾驶证反面
		//上传身份证反面图片到腾讯云cos
		cosUploadVo, err := s.cosService.UploadFile(ctx, file, "driverLicense")
		if err != nil {
			return nil, err
		}
		driverLicenseOcrVo.DriverLicenseBackUrl = cosUploadVo.Url
		driverLicenseOcrVo.DriverLicenseBackShowUrl = cosUploadVo.ShowUrl
	}
	return driverLicenseOcrVo, nil
}
